package cn.com.anysdk.redis.demo.controller;

import cn.com.anysdk.redis.api.IRedisService;
import cn.com.anysdk.redis.event.RedisEventManager;
import cn.com.anysdk.redis.factory.RedisServiceFactory;
import cn.com.anysdk.starter.config.redis.RedisProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * Redis配置展示控制器
 * 用于展示当前Redis配置信息，支持敏感信息脱敏
 */
@RestController
@RequestMapping("/api/redis")
public class RedisConfigController {

    @Autowired
    private RedisProperties redisProperties;
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Autowired
    private RedisEventManager redisEventManager;
    
    // 当前活跃的Redis服务实例
    private IRedisService currentRedisService;

    /**
     * 获取Redis配置信息
     * @return 配置信息（敏感信息已脱敏）
     */
    @GetMapping("/config")
    public Map<String, Object> getRedisConfig() {
        Map<String, Object> result = new HashMap<>();
        result.put("currentEnvironment", redisProperties.getEnvironment());
        result.put("timestamp", System.currentTimeMillis());

        // 本地Redis配置
        result.put("local", buildLocalConfig());

        // 阿里云Redis配置
        result.put("aliyun", buildAliyunConfig());

        // 华为云Redis配置
        result.put("huawei", buildHuaweiConfig());

        // 腾讯云Redis配置
        result.put("tencent", buildTencentConfig());

        return result;
    }

    /**
     * 获取当前环境的Redis配置
     * @return 当前环境的详细配置
     */
    @GetMapping("/current")
    public Map<String, Object> getCurrentConfig() {
        Map<String, Object> result = new HashMap<>();
        result.put("environment", redisProperties.getEnvironment());
        result.put("timestamp", System.currentTimeMillis());

        String env = redisProperties.getEnvironment();
        switch (env) {
            case "local":
                result.put("config", buildLocalConfig());
                break;
            case "aliyun":
                result.put("config", buildAliyunConfig());
                break;
            case "huawei":
                result.put("config", buildHuaweiConfig());
                break;
            case "tencent":
                result.put("config", buildTencentConfig());
                break;
            default:
                result.put("config", buildLocalConfig());
                result.put("warning", "Unknown environment, fallback to local");
                break;
        }

        return result;
    }

    /**
     * 切换Redis环境
     * @param request 包含environment字段的请求体
     * @return 切换结果
     */
    @PostMapping("/environment")
    public Map<String, Object> switchEnvironment(@RequestBody Map<String, String> request) {
        String environment = request.get("environment");
        
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 验证环境参数
            if (environment == null || environment.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "环境参数不能为空");
                return result;
            }
            
            // 验证环境是否支持
            if (!RedisServiceFactory.isSupportedEnvironment(environment)) {
                result.put("success", false);
                result.put("message", "不支持的环境: " + environment + "，支持的环境: local, aliyun");
                return result;
            }
            
            // 获取当前环境
            String currentEnv = redisProperties.getEnvironment();
            
            // 如果环境没有变化，直接返回
            if (environment.equals(currentEnv)) {
                result.put("success", true);
                result.put("message", "当前已经是 " + environment + " 环境");
                result.put("environment", environment);
                result.put("timestamp", System.currentTimeMillis());
                return result;
            }
            
            // 更新配置中的环境
            redisProperties.setEnvironment(environment);
            
            // 创建新的Redis服务实例
            IRedisService newRedisService = RedisServiceFactory.createRedisService(redisProperties, redisEventManager);
            
            // 测试新连接
            try {
                // 简单的ping测试
                newRedisService.set("__test_connection__", "test");
                newRedisService.del("__test_connection__");
                
                // 如果测试成功，更新当前服务实例
                if (currentRedisService != null) {
                    // 这里可以添加清理旧连接的逻辑
                    System.out.println("切换前环境: " + currentEnv);
                }
                
                currentRedisService = newRedisService;
                
                result.put("success", true);
                result.put("message", "成功切换到 " + environment + " 环境");
                result.put("previousEnvironment", currentEnv);
                result.put("currentEnvironment", environment);
                result.put("timestamp", System.currentTimeMillis());
                
                System.out.println("Redis环境切换成功: " + currentEnv + " -> " + environment);
                
            } catch (Exception testException) {
                // 连接测试失败，回滚环境设置
                redisProperties.setEnvironment(currentEnv);
                
                result.put("success", false);
                result.put("message", "切换到 " + environment + " 环境失败: " + testException.getMessage());
                result.put("environment", currentEnv);
                result.put("error", testException.getClass().getSimpleName());
                
                System.err.println("Redis环境切换失败: " + testException.getMessage());
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "切换环境时发生错误: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            
            System.err.println("切换Redis环境时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        
        return result;
    }
    
    /**
     * 获取当前活跃的Redis服务实例
     * @return 当前Redis服务实例
     */
    public IRedisService getCurrentRedisService() {
        if (currentRedisService == null) {
            // 如果没有当前实例，从Spring容器获取默认实例
            try {
                currentRedisService = applicationContext.getBean(IRedisService.class);
            } catch (Exception e) {
                // 如果获取失败，创建一个新实例
                currentRedisService = RedisServiceFactory.createRedisService(redisProperties, redisEventManager);
            }
        }
        return currentRedisService;
    }
    
    /**
     * 测试当前Redis连接
     * @return 连接测试结果
     */
    @GetMapping("/test-connection")
    public Map<String, Object> testConnection() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            IRedisService redisService = getCurrentRedisService();
            
            // 执行简单的Redis操作测试
            String testKey = "__connection_test_" + System.currentTimeMillis();
            String testValue = "test_value";
            
            boolean setResult = redisService.set(testKey, testValue);
            String getValue = redisService.get(testKey);
            boolean delResult = redisService.del(testKey);
            
            boolean connectionOk = setResult && testValue.equals(getValue) && delResult;
            
            result.put("success", connectionOk);
            result.put("environment", redisProperties.getEnvironment());
            result.put("message", connectionOk ? "Redis连接正常" : "Redis连接异常");
            result.put("testDetails", Map.of(
                "setResult", setResult,
                "getValue", getValue,
                "delResult", delResult
            ));
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("environment", redisProperties.getEnvironment());
            result.put("message", "Redis连接测试失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    private Map<String, Object> buildLocalConfig() {
        Map<String, Object> config = new HashMap<>();
        RedisProperties.LocalConfig local = redisProperties.getLocal();

        config.put("host", local.getHost());
        config.put("port", local.getPort());
        config.put("database", local.getDatabase());
        config.put("password", maskPassword(local.getPassword()));

        return config;
    }

    private Map<String, Object> buildAliyunConfig() {
        Map<String, Object> config = new HashMap<>();
        RedisProperties.AliyunConfig aliyun = redisProperties.getAliyun();

        config.put("endpoint", aliyun.getConfig() != null ? aliyun.getConfig().getEndpoint() : null);
        config.put("port", 6379);
        config.put("mode", aliyun.getMode());

        return config;
    }

    private Map<String, Object> buildHuaweiConfig() {
        Map<String, Object> config = new HashMap<>();
        cn.com.anysdk.redis.config.HuaweiRedisConfig huawei = redisProperties.getHuawei();

        config.put("endpoint", huawei.getEndpoint());
        config.put("port", huawei.getPort());
        config.put("accessKey", maskAccessKey(huawei.getAccessKey()));
        config.put("secretKey", maskSecretKey(huawei.getSecretKey()));
        config.put("region", huawei.getRegion());
        config.put("mode", huawei.getMode());

        return config;
    }

    private Map<String, Object> buildTencentConfig() {
        Map<String, Object> config = new HashMap<>();
        cn.com.anysdk.redis.config.TencentRedisConfig tencent = redisProperties.getTencent();

        config.put("endpoint", tencent.getEndpoint());
        config.put("port", tencent.getPort());
        config.put("secretId", maskSecretId(tencent.getSecretId()));
        config.put("secretKey", maskSecretKey(tencent.getSecretKey()));
        config.put("region", tencent.getRegion());
        config.put("mode", tencent.getMode());

        return config;
    }

    /**
     * 脱敏处理密码
     */
    private String maskPassword(String password) {
        if (password == null || password.length() <= 4) {
            return "****";
        }
        return password.substring(0, 2) + "****" + password.substring(password.length() - 2);
    }

    /**
     * 脱敏处理AccessKey
     */
    private String maskAccessKey(String accessKey) {
        if (accessKey == null || accessKey.length() <= 6) {
            return "******";
        }
        return accessKey.substring(0, 3) + "******" + accessKey.substring(accessKey.length() - 3);
    }

    /**
     * 脱敏处理SecretKey
     */
    private String maskSecretKey(String secretKey) {
        if (secretKey == null || secretKey.length() <= 8) {
            return "********";
        }
        return secretKey.substring(0, 4) + "********" + secretKey.substring(secretKey.length() - 4);
    }

    /**
     * 脱敏处理SecretId
     */
    private String maskSecretId(String secretId) {
        if (secretId == null || secretId.length() <= 8) {
            return "********";
        }
        return secretId.substring(0, 4) + "********" + secretId.substring(secretId.length() - 4);
    }
}